---
title: ApiKey
full: true
---

`ApiKey` represents an authentication token that allows programmatic access to your application's backend. API keys can be associated with individual users or teams.

On this page:
- [`ApiKey`](#apikey)
- Types:
  - [`UserApiKey`](#userapikey)
  - [`TeamApiKey`](#teamapikey)

---

# `ApiKey`

API keys provide a way for users to authenticate with your backend services without using their primary credentials. They can be created for individual users or for teams, allowing programmatic access to your application.

API keys can be obtained through:
- [`user.createApiKey()`](../types/user.mdx#currentusercreateapikeyoptions)
- [`user.listApiKeys()`](../types/user.mdx#currentuserlistapikeys)
- [`user.useApiKeys()`](../types/user.mdx#currentuseruseapikeys) (React hook)
- [`team.createApiKey()`](../types/team.mdx#teamcreateapikeyoptions)
- [`team.listApiKeys()`](../types/team.mdx#teamlistapikeys)
- [`team.useApiKeys()`](../types/team.mdx#teamuseapikeys) (React hook)

### Table of Contents

<ClickableTableOfContents title="ApiKey Table of Contents" code={`type ApiKey<Type extends "user" | "team" = "user" | "team", IsFirstView extends boolean = false> = {
    id: string;  //$stack-link-to:#apikeyid
    description: string;  //$stack-link-to:#apikeydescription
    expiresAt?: Date;  //$stack-link-to:#apikeyexpiresat
    manuallyRevokedAt: Date | null;  //$stack-link-to:#apikeymanuallyrevokedat
    createdAt: Date;  //$stack-link-to:#apikeycreatedat
    value: IsFirstView extends true ? string : { lastFour: string };  //$stack-link-to:#apikeyvalue
    
    // User or Team properties based on Type
    ...(Type extends "user" ? {
      type: "user";
      userId: string;  //$stack-link-to:#apikeyuserid
    } : {
      type: "team";
      teamId: string;  //$stack-link-to:#apikeyteamid
    })
    
    // Methods
    isValid(): boolean;  //$stack-link-to:#apikeyisvalid
    whyInvalid(): "manually-revoked" | "expired" | null;  //$stack-link-to:#apikeywhyinvalid
    revoke(): Promise<void>;  //$stack-link-to:#apikeyrevoke
    update(options): Promise<void>;  //$stack-link-to:#apikeyupdateoptions
};`} />

---

<CollapsibleTypesSection type="apiKey" property="id" defaultOpen={false}>
  <MethodLayout>
    <MethodContent>
      The unique identifier for this API key.
    </MethodContent>
    <MethodAside title="Type Definition">

      ```typescript
      declare const id: string;
      ```
    </MethodAside>
  </MethodLayout>
</CollapsibleTypesSection>

<CollapsibleTypesSection type="apiKey" property="description" defaultOpen={false}>
  <MethodLayout>
    <MethodContent>
      A human-readable description of the API key's purpose.
    </MethodContent>
    <MethodAside title="Type Definition">

      ```typescript
      declare const description: string;
      ```
    </MethodAside>
  </MethodLayout>
</CollapsibleTypesSection>

<CollapsibleTypesSection type="apiKey" property="expiresAt" defaultOpen={false}>
  <MethodLayout>
    <MethodContent>
      The date and time when this API key will expire. If not set, the key does not expire.
    </MethodContent>
    <MethodAside title="Type Definition">

      ```typescript
      declare const expiresAt?: Date;
      ```
    </MethodAside>
  </MethodLayout>
</CollapsibleTypesSection>

<CollapsibleTypesSection type="apiKey" property="manuallyRevokedAt" defaultOpen={false}>
  <MethodLayout>
    <MethodContent>
      The date and time when this API key was manually revoked. If null, the key has not been revoked.
    </MethodContent>
    <MethodAside title="Type Definition">

      ```typescript
      declare const manuallyRevokedAt: Date | null;
      ```
    </MethodAside>
  </MethodLayout>
</CollapsibleTypesSection>

<CollapsibleTypesSection type="apiKey" property="createdAt" defaultOpen={false}>
  <MethodLayout>
    <MethodContent>
      The date and time when this API key was created.
    </MethodContent>
    <MethodAside title="Type Definition">

      ```typescript
      declare const createdAt: Date;
      ```
    </MethodAside>
  </MethodLayout>
</CollapsibleTypesSection>

<CollapsibleTypesSection type="apiKey" property="value" defaultOpen={false}>
  <MethodLayout>
    <MethodContent>
      The value of the API key. When the key is first created, this is the full API key string. After that, only the last four characters are available for security reasons.
    </MethodContent>
    <MethodAside title="Type Definition">

      ```typescript
      // On first creation
      declare const value: string;

      // On subsequent retrievals
      declare const value: { lastFour: string };
      ```
    </MethodAside>
  </MethodLayout>
</CollapsibleTypesSection>

<CollapsibleTypesSection type="apiKey" property="userId" defaultOpen={false}>
  <MethodLayout>
    <MethodContent>
      For user API keys, the ID of the user that owns this API key.
    </MethodContent>
    <MethodAside title="Type Definition">

      ```typescript
      declare const userId: string;
      ```
    </MethodAside>
  </MethodLayout>
</CollapsibleTypesSection>

<CollapsibleTypesSection type="apiKey" property="teamId" defaultOpen={false}>
  <MethodLayout>
    <MethodContent>
      For team API keys, the ID of the team that owns this API key.
    </MethodContent>
    <MethodAside title="Type Definition">

      ```typescript
      declare const teamId: string;
      ```
    </MethodAside>
  </MethodLayout>
</CollapsibleTypesSection>

<CollapsibleTypesSection type="apiKey" property="isValid" defaultOpen={false}>
  <MethodLayout>
    <MethodContent>
      Checks if the API key is still valid (not expired and not revoked).

      ### Parameters

      None.

      ### Returns

      `boolean`: True if the key is valid, false otherwise.
    </MethodContent>
    <MethodAside>
      <AsideSection title="Signature">

      ```typescript
      declare function isValid(): boolean;
      ```
      </AsideSection>
      <AsideSection title="Examples">
      ```typescript Checking if an API key is valid
      if (apiKey.isValid()) {
        console.log("API key is still valid");
      } else {
        console.log("API key is invalid");
      }
      ```
      </AsideSection>
    </MethodAside>
  </MethodLayout>
</CollapsibleTypesSection>

<CollapsibleTypesSection type="apiKey" property="whyInvalid" defaultOpen={false}>
  <MethodLayout>
    <MethodContent>
      Returns the reason why the API key is invalid, or null if it is valid.

      ### Parameters

      None.

      ### Returns

      `"manually-revoked" | "expired" | null`: The reason the key is invalid, or null if it's valid.
    </MethodContent>
    <MethodAside>
      <AsideSection title="Signature">

      ```typescript
      declare function whyInvalid(): "manually-revoked" | "expired" | null;
      ```
      </AsideSection>
      <AsideSection title="Examples">
      ```typescript Checking why an API key is invalid
      const reason = apiKey.whyInvalid();
      if (reason) {
        console.log(`API key is invalid because it was ${reason}`);
      } else {
        console.log("API key is valid");
      }
      ```
      </AsideSection>
    </MethodAside>
  </MethodLayout>
</CollapsibleTypesSection>

<CollapsibleTypesSection type="apiKey" property="revoke" defaultOpen={false}>
  <MethodLayout>
    <MethodContent>
      Revokes the API key, preventing it from being used for authentication.

      ### Parameters

      None.

      ### Returns

      `Promise<void>`
    </MethodContent>
    <MethodAside>
      <AsideSection title="Signature">

      ```typescript
      declare function revoke(): Promise<void>;
      ```
      </AsideSection>
      <AsideSection title="Examples">
      ```typescript Revoking an API key
      await apiKey.revoke();
      console.log("API key has been revoked");
      ```
      </AsideSection>
    </MethodAside>
  </MethodLayout>
</CollapsibleTypesSection>

<CollapsibleTypesSection type="apiKey" property="update" signature="options" defaultOpen={false}>
  <MethodLayout>
    <MethodContent>
      Updates the API key properties.

      ### Parameters

      <ParamField path="options" type="object" required>
        An object containing properties for updating.
        <Accordion title="Show Properties">
          <ParamField path="description" type="string">
            A new description for the API key.
          </ParamField>
          <ParamField path="expiresAt" type="Date | null">
            A new expiration date, or null to remove the expiration.
          </ParamField>
          <ParamField path="revoked" type="boolean">
            Set to true to revoke the API key.
          </ParamField>
        </Accordion>
      </ParamField>

      ### Returns

      `Promise<void>`
    </MethodContent>
    <MethodAside>
      <AsideSection title="Signature">

      ```typescript
      declare function update(options: {
        description?: string;
        expiresAt?: Date | null;
        revoked?: boolean;
      }): Promise<void>;
      ```
      </AsideSection>
      <AsideSection title="Examples">
      ```typescript Updating an API key
      await apiKey.update({
        description: "Updated description",
        expiresAt: new Date(Date.now() + 60 * 24 * 60 * 60 * 1000), // 60 days
      });
      ```
      </AsideSection>
    </MethodAside>
  </MethodLayout>
</CollapsibleTypesSection>

---

# Types

<CollapsibleTypesSection type="" property="UserApiKey" defaultOpen={false}>
  <MethodLayout>
    <MethodContent>
      A type alias for an API key owned by a user.
    </MethodContent>
    <MethodAside title="Type Definition">

      ```typescript
      type UserApiKey = ApiKey<"user", false>;
      ```
    </MethodAside>
  </MethodLayout>
</CollapsibleTypesSection>

<CollapsibleTypesSection type="" property="UserApiKeyFirstView" defaultOpen={false}>
  <MethodLayout>
    <MethodContent>
      A type alias for a newly created user API key, which includes the full key value instead of just the last four characters.
    </MethodContent>
    <MethodAside title="Type Definition">

      ```typescript
      type UserApiKeyFirstView = ApiKey<"user", true>;
      ```
    </MethodAside>
  </MethodLayout>
</CollapsibleTypesSection>

<CollapsibleTypesSection type="" property="TeamApiKey" defaultOpen={false}>
  <MethodLayout>
    <MethodContent>
      A type alias for an API key owned by a team.
    </MethodContent>
    <MethodAside title="Type Definition">

      ```typescript
      type TeamApiKey = ApiKey<"team", false>;
      ```
    </MethodAside>
  </MethodLayout>
</CollapsibleTypesSection>

<CollapsibleTypesSection type="" property="TeamApiKeyFirstView" defaultOpen={false}>
  <MethodLayout>
    <MethodContent>
      A type alias for a newly created team API key, which includes the full key value instead of just the last four characters.
    </MethodContent>
    <MethodAside title="Type Definition">

      ```typescript
      type TeamApiKeyFirstView = ApiKey<"team", true>;
      ```
    </MethodAside>
  </MethodLayout>
</CollapsibleTypesSection>

---

# Creation Options

When creating an API key using [`user.createApiKey()`](../types/user.mdx#currentusercreatekeyoptions) or [`team.createApiKey()`](../types/team.mdx#teamcreatekeyoptions), you need to provide an options object.

<MethodLayout>
  <MethodContent>
    The options object for creating an API key.

    ### Properties

    <ParamField path="description" type="string" required>
      A human-readable description of the API key's purpose.
    </ParamField>
    <ParamField path="expiresAt" type="Date | null" required>
      The date when the API key will expire. Use null for keys that don't expire.
    </ParamField>
    <ParamField path="isPublic" type="boolean">
      Whether the API key is public. Defaults to false.
      
      - **Secret API Keys** (default) are monitored by Stack Auth's secret scanner, which can revoke them if detected in public code repositories.
      - **Public API Keys** are designed for client-side code where exposure is not a concern.
    </ParamField>
  </MethodContent>
  <MethodAside>
    <AsideSection title="Type Definition">

    ```typescript
    type ApiKeyCreationOptions = {
      description: string;
      expiresAt: Date | null;
      isPublic?: boolean;
    };
    ```
    </AsideSection>
    <AsideSection title="Examples">
    ```typescript Creating a user API key
    // Get the current user
    const user = await stackApp.getUser();

    // Create a secret API key (default)
    const secretKey = await user.createApiKey({
      description: "Backend integration",
      expiresAt: new Date(Date.now() + 90 * 24 * 60 * 60 * 1000), // 90 days
      isPublic: false,
    });

    // Create a public API key
    const publicKey = await user.createApiKey({
      description: "Client-side access",
      expiresAt: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000), // 30 days
      isPublic: true,
    });
    ```
    </AsideSection>
  </MethodAside>
</MethodLayout>
